#include "cursor_monitor.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xfixes.h>

// 库版本信息
#define CURSOR_MONITOR_VERSION "1.0.0"

// 内部函数声明
static CursorStatus* get_cursor_status_basic(Display* display);
static CursorStatus* get_cursor_status_xfixes(Display* display);
static CursorStatus* get_cursor_status_safe(Display* display);

Display* cursor_monitor_init(void) {
    Display* display = XOpenDisplay(NULL);
    if (!display) {
        fprintf(stderr, "无法打开X显示连接\n");
        return NULL;
    }
    return display;
}

void cursor_monitor_cleanup(Display* display) {
    if (display) {
        XCloseDisplay(display);
    }
}

CursorStatus* cursor_monitor_get_status(Display* display) {
    if (!display) {
        fprintf(stderr, "无效的Display指针\n");
        return NULL;
    }
    
    CursorStatus* status = NULL;
    
    // 优先尝试安全方法
    status = get_cursor_status_safe(display);
    if (status) {
        return status;
    }
    
    // 如果安全方法失败，尝试XFixes方法
    status = get_cursor_status_xfixes(display);
    if (status) {
        return status;
    }
    
    // 如果仍然失败，使用基本方法
    return get_cursor_status_basic(display);
}

unsigned long cursor_monitor_get_id(Display* display) {
    if (!display) {
        return 0;
    }
    
    CursorStatus* status = cursor_monitor_get_status(display);
    if (!status) {
        return 0;
    }
    
    unsigned long cursor_id = status->cursor_id;
    cursor_monitor_free_status(status);
    
    return cursor_id;
}

int cursor_monitor_get_position(Display* display, int* x, int* y) {
    if (!display || !x || !y) {
        return 0;
    }
    
    CursorStatus* status = cursor_monitor_get_status(display);
    if (!status) {
        return 0;
    }
    
    *x = status->x;
    *y = status->y;
    cursor_monitor_free_status(status);
    
    return 1;
}

void cursor_monitor_free_status(CursorStatus* status) {
    if (status) {
        free(status);
    }
}

int cursor_monitor_xfixes_available(Display* display) {
    if (!display) {
        return 0;
    }
    
    int event_base, error_base;
    return XFixesQueryExtension(display, &event_base, &error_base);
}

const char* cursor_monitor_get_version(void) {
    return CURSOR_MONITOR_VERSION;
}

// 内部函数实现

static CursorStatus* get_cursor_status_basic(Display* display) {
    CursorStatus* status = malloc(sizeof(CursorStatus));
    if (!status) {
        fprintf(stderr, "内存分配失败\n");
        return NULL;
    }
    
    // 初始化
    memset(status, 0, sizeof(CursorStatus));
    status->cursor_id = 0;
    
    Window root, child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    
    // 获取根窗口
    root = DefaultRootWindow(display);
    
    // 获取指针信息
    if (XQueryPointer(display, root, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
        status->x = root_x;
        status->y = root_y;
        status->is_visible = 1;
    } else {
        fprintf(stderr, "基本方法: 无法获取指针信息\n");
        free(status);
        return NULL;
    }
    
    return status;
}

static CursorStatus* get_cursor_status_xfixes(Display* display) {
    // 检查XFixes扩展是否可用
    int event_base, error_base;
    if (!XFixesQueryExtension(display, &event_base, &error_base)) {
        return NULL;
    }
    
    CursorStatus* status = malloc(sizeof(CursorStatus));
    if (!status) {
        return NULL;
    }
    
    // 初始化
    memset(status, 0, sizeof(CursorStatus));
    status->cursor_id = 0;
    
    // 获取光标图像信息
    XFixesCursorImage* cursor_image = XFixesGetCursorImage(display);
    if (cursor_image) {
        // 获取位置信息
        status->x = cursor_image->x;
        status->y = cursor_image->y;
        
        // 获取光标尺寸
        status->width = cursor_image->width;
        status->height = cursor_image->height;
        
        // 获取光标序列号
        status->cursor_id = cursor_image->cursor_serial;
        
        status->is_visible = (cursor_image->width > 0 && cursor_image->height > 0);
        
        // 释放光标图像资源
        XFree(cursor_image);
    } else {
        free(status);
        return NULL;
    }
    
    return status;
}

static CursorStatus* get_cursor_status_safe(Display* display) {
    CursorStatus* status = malloc(sizeof(CursorStatus));
    if (!status) {
        return NULL;
    }
    
    // 初始化
    memset(status, 0, sizeof(CursorStatus));
    status->cursor_id = 0;
    
    Window root, child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    
    // 获取根窗口
    root = DefaultRootWindow(display);
    
    // 获取指针信息
    if (XQueryPointer(display, root, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
        status->x = root_x;
        status->y = root_y;
        status->is_visible = 1;
        
        // 使用XFixes获取额外信息（如果可用）
        int event_base, error_base;
        if (XFixesQueryExtension(display, &event_base, &error_base)) {
            XFixesCursorImage* cursor_image = XFixesGetCursorImage(display);
            if (cursor_image) {
                status->width = cursor_image->width;
                status->height = cursor_image->height;
                status->cursor_id = cursor_image->cursor_serial;
                XFree(cursor_image);
            }
        }
    } else {
        free(status);
        return NULL;
    }
    
    return status;
}